package com.xygz.orm;

import com.xygz.orm.constants.ErrorMessages;
import com.xygz.orm.constants.ORMConstants;
import com.xygz.orm.enums.SQLKeywords;
import com.xygz.orm.exception.ORMException;
import com.xygz.orm.internal.query.Condition;
import com.xygz.orm.internal.query.Ops;
import com.xygz.orm.internal.query.WhereItem;
import com.xygz.orm.model.ColumnData;
import com.xygz.orm.table.ZTable;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * SQL 条件查询器
 *
 * @author xiyuan-lgz 2023-09-19 @version v1.0.0 新建与整理
 */
@SuppressWarnings({"all"})
public abstract class ConditionWrapper<T, Child extends ConditionWrapper<T, Child>> extends ConditionCheck<T, Child> implements SQLWhere<Child>, ToSQL, Serializable, ORMConstants, ErrorMessages {
    static final AtomicLong instance = new AtomicLong(0);
    
    // 生成SQL标记
    protected volatile boolean buildingSQL = false;
    
    protected boolean isBuildingSQL() {
        return this.buildingSQL;
    }
    
    /**
     * 设置sql 构建中 返回修改前的指标
     *
     * @param buildingSQL 构建中
     * @return previous building State
     */
    protected boolean setBuildingSQL(boolean buildingSQL) {
        boolean ss = this.buildingSQL;
        this.buildingSQL = buildingSQL;
        return ss;
    }
    
    protected static <E, C extends ConditionWrapper<E, C>> C create(Class<C> cc, Class<E> ce) {
        Objects.requireNonNull(cc);
        Objects.requireNonNull(ce);
        return ORMManager.createConditioner(cc, ce);
    }
    
    protected static <E, C extends ConditionWrapper<E, C>> C create(Class<C> cc, E en) {
        Objects.requireNonNull(en);
        Objects.requireNonNull(cc);
        C c = ORMManager.createConditioner(cc, en);
        c.init(en);
        return c;
    }
    
    protected final ORMManager manager;
    private final Map<String, WhereItem> wheres;
    private Class<T> rawType;
    
    
    private ConditionWrapper() throws ORMException {
        this.manager = ORMManager.instance();
        this.wheres = new LinkedHashMap<String, WhereItem>(3);
    }
    
    protected ConditionWrapper(Class<T> rawType) throws ORMException {
        this();
        this.rawType = rawType;
    }
    
    protected ConditionWrapper(T e) throws ORMException {
        this();
        this.rawType = (Class<T>) e.getClass();
        this.init(e);
    }
    
    
    /**
     * 获取泛型类型
     *
     * @return 表类型
     */
    public Class<T> getRawType() {
        return rawType;
    }
    
    
    /**
     * 获取条件数量
     *
     * @return 条件数量
     */
    public int getConditionCount() {
        return wheres.size();
    }
    
    /**
     * 返回子类实例
     *
     * @return 返回子类实例
     */
    protected Child self() {
        return (Child) this;
    }
    
    protected abstract void init(T en);
    
    /**
     * 获取SQL表名别名
     *
     * @return 或者别名
     */
    public abstract String getTableName();
    
    /**
     * 获取数据库表
     *
     * @return 表对象
     */
    public abstract ZTable getTable();
    
    
    /*******************************************************************/
    // 条件组
    /*******************************************************************/
    /**
     * 添加以"（）"包裹条件组.
     * <p>
     * 例如：select * from tableA where c1=9 or (c2=0 and c3=1 or c4=0)
     *
     * @param <W>  包裹器类型.compose
     * @param isOR 是否为or 类型
     * @return 条件包裹器
     */
    public abstract <W extends Wrapper<T, Child, W>> Wrapper<T, Child, W> newWrapper(Boolean isOR);
    
    /**
     * 添加以"（）"包裹的and条件组. 如果需要修改为 or 条件 可以调用 setWrapperType(true) 设置为or类型
     * <p>
     * 例如：select * from tableA where c1=9 or (c2=0 and c3=1 or c4=0)
     *
     * @param <W> 包裹器类型.compose
     * @return 条件包裹器
     */
    public final <W extends Wrapper<T, Child, W>> Wrapper<T, Child, W> newWrapper() {
        return newWrapper(false);
    }
    
    
    /**
     * 添加以"（）"包裹or条件组.
     * <p>
     * 例如：select * from tableA where c1=9 or (c2=0 and c3=1 or c4=0)
     *
     * @param <W> 包裹器类型.compose
     * @return 条件包裹器
     */
    public <W extends Wrapper<T, Child, W>> Wrapper<T, Child, W> or() {
        Wrapper<T, Child, W> wrapper = this.newWrapper(true);
        this.addCondition(wrapper);
        return wrapper;
    }
    
    /**
     * 添加以"（）"包裹or条件组.
     * <p>
     * 例如：select * from tableA where c1=9 or (c2=0 and c3=1 or c4=0)
     *
     * @param <W>      包裹器类型.compose
     * @param consumer 自定义条件构造器
     * @return 条件包裹器
     */
    public <W extends Wrapper<T, Child, W>> Child or(Consumer<Wrapper<T, Child, W>> consumer) {
        return or(true, consumer);
    }
    
    /**
     * 添加以"（）"包裹or条件组.
     * <p>
     * 例如：select * from tableA where c1=9 or (c2=0 and c3=1 or c4=0)
     *
     * @param <W>      包裹器类型.compose
     * @param flag     如果flag = true 则添加条件 反之不添加
     * @param consumer 自定义条件构造器
     * @return 条件包裹器
     */
    public <W extends Wrapper<T, Child, W>> Child or(boolean flag, Consumer<Wrapper<T, Child, W>> consumer) {
        if (flag && consumer != null) {
            Wrapper<T, Child, W> wrapper = this.newWrapper(true);
            consumer.accept(wrapper);
            this.addCondition(wrapper);
        }
        return self();
    }
    
    
    /**
     * 添加以"（）"包裹and 条件组，
     * <p>
     * 例如：select * from tableA where c1=9 and (c2=0 and c3=1 or c4=0)
     *
     * @param <W> 包裹器类型
     * @return 条件包裹器
     */
    public <W extends Wrapper<T, Child, W>> Wrapper<T, Child, W> and() {
        Wrapper<T, Child, W> wrapper = this.newWrapper(false);
        this.addCondition(wrapper);
        return wrapper;
    }
    
    /**
     * 添加以"（）"包裹and 条件组，
     * <p>
     * 例如：select * from tableA where c1=9 and (c2=0 and c3=1 or c4=0)
     *
     * @param <W>      包裹器类型
     * @param consumer 自定义条件构造器
     * @return 条件包裹器
     */
    public <W extends Wrapper<T, Child, W>> Child and(Consumer<Wrapper<T, Child, W>> consumer) {
        return and(true, consumer);
    }
    
    /**
     * 添加以"（）"包裹and 条件组，
     * <p>
     * 例如：select * from tableA where c1=9 and (c2=0 and c3=1 or c4=0)
     *
     * @param <W>      包裹器类型
     * @param consumer 自定义条件构造器
     * @param flag     如果flag = true 则添加条件 反之不添加
     * @return 条件包裹器
     */
    public <W extends Wrapper<T, Child, W>> Child and(boolean flag, Consumer<Wrapper<T, Child, W>> consumer) {
        if (flag && consumer != null) {
            Wrapper<T, Child, W> wrapper = this.newWrapper(false);
            consumer.accept(wrapper);
            this.addCondition(wrapper);
        }
        return self();
    }
    
    //
    // /**
    //  * 删除条件
    //  *
    //  * @param isOr     是否 为or条件
    //  * @param column   列信息
    //  * @param keywords 条件关键字
    //  * @param value    参数值
    //  * @return 当前查询器
    //  */
    // public Child removeCondition(boolean isOr, String column, SQLKeywords keywords, Object value) {
    //     throw new UnsupportedOperationException("Not implemented");// 尚未支持
    //     // return remove(createCondition(isOr, keywords, column, value).stringID());
    // }
    //
    // /**
    //  * 删除条件
    //  *
    //  * @param isOr     是否 为or条件
    //  * @param column   列信息
    //  * @param keywords 条件关键字
    //  * @param value    参数值
    //  * @return 当前查询器
    //  */
    // public Child removeCondition(boolean isOr, SFunc<E, ?> column, SQLKeywords keywords, Object value) {
    //     throw new UnsupportedOperationException("Not implemented");// 尚未支持
    //     // return remove(createCondition(isOr, keywords, column, value).stringID());
    // }
    
    
    /**
     * 增加查询条件
     * 这是一个受保护的方法，用于向查询条件集合中添加新的条件
     *
     * @param condition 条件对象，用于指定查询的过滤条件
     * @return 返回子类实例，支持链式调用
     * @throws IllegalArgumentException 当传入的条件为null时抛出此异常
     */
    private Child addCondition(WhereItem condition) throws IllegalArgumentException {
        // 检查条件是否为null，如果为null则直接返回当前实例
        if (null == condition) return self();
        
        // 检查添加条件是否会导致栈溢出，这是一种安全检查机制
        checkConditionStackOverflow(condition);
        // 将条件添加到条件集合中，使用stringID()作为键
        wheres.put(condition.stringID(), condition);
        // 返回当前实例，支持链式调用
        return self();
    }
    
    /**
     * 获取查询器的条件列表
     *
     * @return 条件列表
     */
    public List<WhereItem> getConditions() {
        return new ArrayList<WhereItem>(wheres.values());
    }
    
    /**
     * 添加条件 组，如果需要 设置当前条件组为 or 条件，需要调用: wrapper.setWrapperType(Wrapper.WrapperType.OR),
     *
     * @param wrapper 条件组
     * @return 当前查询器
     */
    public Child addCondition(Wrapper wrapper) {
        return this.addCondition((WhereItem) wrapper);
    }
    
    protected Child removeCondition(String id) {
        Optional.ofNullable(id).ifPresent(wheres::remove);
        return self();
    }
    
    
    protected <E> Condition<E> createCondition(boolean isOr, SQLKeywords kwd, String column, Object value) throws IllegalArgumentException {
        ColumnData<String, Class<E>> col = this.parseAndValidateColumn(column);
        return manager.getConditionBuilder().create(col.getValue1(), isOr, col.getColumn(), kwd, value);
    }
    
    protected <E> Condition<E> createCondition(boolean isOr, SQLKeywords kwd, SFunc<E, ?> column, Object value) throws IllegalArgumentException {
        ColumnData<SFunc<E, ?>, Class<E>> col = this.parseAndValidateColumn(column);
        return manager.getConditionBuilder().create(col.getValue(), isOr, col.getColumn(), kwd, value);
    }
    
    protected <E> Condition<E> createCondition(boolean isOr, SQLKeywords kwd, String column) throws IllegalArgumentException {
        return createCondition(isOr, kwd, column, null);
    }
    
    protected <E> Condition<E> createCondition(boolean isOr, SQLKeywords kwd, SFunc<E, ?> column) throws IllegalArgumentException {
        return createCondition(isOr, kwd, column, null);
    }
    
    protected <E> Condition<E> createExpression(boolean isOr, Ops opt, String column, String expression, Object param) throws IllegalArgumentException {
        return manager.getConditionBuilder().createExpression(getRawType(), isOr, column, opt, expression, param);
    }
    
    protected <E> Condition<E> createExpression(boolean isOr, Ops opt, SFunc<E, ?> column, String expression, Object param) throws IllegalArgumentException {
        return manager.getConditionBuilder().createExpression(getRawType(), isOr, column, opt, expression, param);
    }
    
    // ***********************************************************************************************************************
    // 以下 实现 SQL where 方法
    // ***********************************************************************************************************************
    
    @Override
    public Child isNull(boolean flag, String column) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IS_NULL, column));
    }
    
    
    @Override
    public <E> Child isNull(boolean flag, SFunc<E, ?> column) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IS_NULL, column));
    }
    
    @Override
    public Child isNotNull(boolean flag, String column) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IS_NOT_NULL, column));
    }
    
    @Override
    public <E> Child isNotNull(boolean flag, SFunc<E, ?> column) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IS_NOT_NULL, column));
    }
    
    @Override
    public Child eq(boolean flag, String column, Object val) {
        if (!flag) return self();
        return addCondition(createCondition(false, SQLKeywords.EQ, column, val));
    }
    
    @Override
    public <E> Child eq(boolean flag, SFunc<E, ?> column, Object val) {
        if (!flag) return self();
        return addCondition(createCondition(false, SQLKeywords.EQ, column, val));
    }
    
    @Override
    public Child ne(boolean flag, String column, Object val) {
        if (!flag) return self();
        return val == null ? isNotNull(column) : addCondition(createCondition(false, SQLKeywords.NE, column, val));
    }
    
    @Override
    public <E> Child ne(boolean flag, SFunc<E, ?> column, Object val) {
        if (!flag) return self();
        return val == null ? isNotNull(column) : addCondition(createCondition(false, SQLKeywords.NE, column, val));
    }
    
    @Override
    public Child lt(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LT, column, val));
    }
    
    @Override
    public <E> Child lt(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LT, column, val));
    }
    
    @Override
    public Child lte(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LE, column, val));
    }
    
    @Override
    public <E> Child lte(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LE, column, val));
    }
    
    @Override
    public Child gte(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.GE, column, val));
    }
    
    @Override
    public <E> Child gte(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.GE, column, val));
    }
    
    @Override
    public Child gt(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.GT, column, val));
    }
    
    @Override
    public <E> Child gt(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.GT, column, val));
    }
    
    @Override
    public <Sub, E> Child in(boolean flag, SFunc<E, ?> column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IN, column, subQuery));
    }
    
    @Override
    public <Sub> Child in(boolean flag, String column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IN, column, subQuery));
    }
    
    @Override
    public Child in(boolean flag, String column, Object... val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IN, column, val));
    }
    
    @Override
    public Child in(boolean flag, String column, Collection<Object> val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IN, column, val));
    }
    
    @Override
    public <E> Child in(boolean flag, SFunc<E, ?> column, Object... val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IN, column, val));
    }
    
    @Override
    public <E> Child in(boolean flag, SFunc<E, ?> column, Collection<Object> val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.IN, column, val));
    }
    
    
    @Override
    public <Sub, E> Child notIn(boolean flag, SFunc<E, ?> column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_IN, column, subQuery));
    }
    
    @Override
    public <Sub> Child notIn(boolean flag, String column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_IN, column, subQuery));
    }
    
    @Override
    public Child notIn(boolean flag, String column, Object... val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_IN, column, val));
    }
    
    @Override
    public Child notIn(boolean flag, String column, Collection<Object> val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_IN, column, val));
    }
    
    @Override
    public <E> Child notIn(boolean flag, SFunc<E, ?> column, Object... val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_IN, column, val));
    }
    
    @Override
    public <E> Child notIn(boolean flag, SFunc<E, ?> column, Collection<Object> val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_IN, column, val));
    }
    
    @Override
    public Child between(boolean flag, String column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public <E> Child between(boolean flag, SFunc<E, ?> column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public Child notBetween(boolean flag, String column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public <E> Child notBetween(boolean flag, SFunc<E, ?> column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public Child like(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LIKE, column, val));
    }
    
    @Override
    public <E> Child like(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LIKE, column, val));
        
    }
    
    @Override
    public Child likeLeft(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LIKE_L, column, val));
    }
    
    @Override
    public <E> Child likeLeft(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LIKE_L, column, val));
    }
    
    @Override
    public Child likeRight(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LIKE_R, column, val));
    }
    
    @Override
    public <E> Child likeRight(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.LIKE_R, column, val));
    }
    
    @Override
    public Child notLike(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_LIKE, column, val));
    }
    
    @Override
    public <E> Child notLike(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_LIKE, column, val));
    }
    
    @Override
    public Child notLikeLeft(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_LIKE_L, column, val));
    }
    
    @Override
    public <E> Child notLikeLeft(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_LIKE_L, column, val));
    }
    
    @Override
    public Child notLikeRight(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_LIKE_R, column, val));
    }
    
    
    @Override
    public <E> Child notLikeRight(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(false, SQLKeywords.NOT_LIKE_R, column, val));
    }
    
    /***********************************************************************************************************************/
    /***********************************************************************************************************************/
    @Override
    public Child orIsNull(boolean flag, String column) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IS_NULL, column));
    }
    
    @Override
    public <E> Child orIsNull(boolean flag, SFunc<E, ?> column) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IS_NULL, column));
    }
    
    @Override
    public Child orIsNotNull(boolean flag, String column) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IS_NOT_NULL, column));
    }
    
    @Override
    public <E> Child orIsNotNull(boolean flag, SFunc<E, ?> column) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IS_NOT_NULL, column));
    }
    
    @Override
    public Child orEq(boolean flag, String column, Object val) {
        if (!flag) return self();
        return val == null ? orIsNull(column) : addCondition(createCondition(true, SQLKeywords.EQ, column, val));
    }
    
    @Override
    public <E> Child orEq(boolean flag, SFunc<E, ?> column, Object val) {
        if (!flag) return self();
        return val == null ? orIsNull(column) : addCondition(createCondition(true, SQLKeywords.EQ, column, val));
    }
    
    @Override
    public Child orNe(boolean flag, String column, Object val) {
        if (!flag) return self();
        return val == null ? orIsNotNull(column) : addCondition(createCondition(true, SQLKeywords.NE, column, val));
    }
    
    @Override
    public <E> Child orNe(boolean flag, SFunc<E, ?> column, Object val) {
        if (!flag) return self();
        return val == null ? orIsNotNull(column) : addCondition(createCondition(true, SQLKeywords.NE, column, val));
    }
    
    @Override
    public Child orLt(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LT, column, val));
    }
    
    @Override
    public <E> Child orLt(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LT, column, val));
    }
    
    @Override
    public Child orLte(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LE, column, val));
    }
    
    @Override
    public <E> Child orLte(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LE, column, val));
    }
    
    @Override
    public Child orGte(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.GE, column, val));
    }
    
    @Override
    public <E> Child orGte(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.GE, column, val));
    }
    
    @Override
    public Child orGt(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.GT, column, val));
    }
    
    @Override
    public <E> Child orGt(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.GT, column, val));
    }
    
    @Override
    public <Sub> Child orIn(boolean flag, String column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IN, column, subQuery));
    }
    
    @Override
    public <Sub, E> Child orIn(boolean flag, SFunc<E, ?> column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IN, column, subQuery));
    }
    
    @Override
    public Child orIn(boolean flag, String column, Object... vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IN, column, vals));
    }
    
    @Override
    public Child orIn(boolean flag, String column, Collection<Object> vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IN, column, vals));
    }
    
    @Override
    public <E> Child orIn(boolean flag, SFunc<E, ?> column, Object... vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IN, column, vals));
    }
    
    @Override
    public <E> Child orIn(boolean flag, SFunc<E, ?> column, Collection<Object> vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.IN, column, vals));
    }
    
    
    @Override
    public <Sub> Child orNotIn(boolean flag, String column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_IN, column, subQuery));
    }
    
    @Override
    public <Sub, E> Child orNotIn(boolean flag, SFunc<E, ?> column, Selector<Sub> subQuery) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_IN, column, subQuery));
    }
    
    @Override
    public Child orNotIn(boolean flag, String column, Object... vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_IN, column, vals));
    }
    
    @Override
    public Child orNotIn(boolean flag, String column, Collection<Object> vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_IN, column, vals));
    }
    
    @Override
    public <E> Child orNotIn(boolean flag, SFunc<E, ?> column, Object... vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_IN, column, vals));
    }
    
    @Override
    public <E> Child orNotIn(boolean flag, SFunc<E, ?> column, Collection<Object> vals) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_IN, column, vals));
    }
    
    @Override
    public Child orBetween(boolean flag, String column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public <E> Child orBetween(boolean flag, SFunc<E, ?> column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public Child orNotBetween(boolean flag, String column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public <E> Child orNotBetween(boolean flag, SFunc<E, ?> column, Object start, Object end) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_BETWEEN, column, new Object[]{start, end}));
    }
    
    @Override
    public Child orLike(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LIKE, column, val));
    }
    
    @Override
    public <E> Child orLike(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LIKE, column, val));
    }
    
    @Override
    public Child orLikeLeft(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LIKE_L, column, val));
    }
    
    @Override
    public <E> Child orLikeLeft(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LIKE_L, column, val));
    }
    
    @Override
    public Child orLikeRight(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LIKE_R, column, val));
    }
    
    @Override
    public <E> Child orLikeRight(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.LIKE_R, column, val));
    }
    
    @Override
    public Child orNotLike(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_LIKE, column, val));
    }
    
    @Override
    public <E> Child orNotLike(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_LIKE, column, val));
    }
    
    @Override
    public Child orNotLikeLeft(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_LIKE_L, column, val));
    }
    
    @Override
    public <E> Child orNotLikeLeft(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_LIKE_L, column, val));
    }
    
    @Override
    public Child orNotLikeRight(boolean flag, String column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_LIKE_R, column, val));
    }
    
    @Override
    public <E> Child orNotLikeRight(boolean flag, SFunc<E, ?> column, Object val) {
        return addCondition(!flag ? null : createCondition(true, SQLKeywords.NOT_LIKE_R, column, val));
    }
    
    /**************************************************************************************************************************/
    /**************************************************************************************************************************/
    /******************  expression 表达式 *************************************************************************************/
    /**************************************************************************************************************************/
    /**************************************************************************************************************************/
    
    
    /**
     * 添加表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param isOR       是否为 or 条件
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @return 当前查询器
     */
    public Child expression(boolean flag, boolean isOR, String column, Ops opt, String expression,
                            Object... params) {
        return addCondition(!flag ? null : createExpression(isOR, opt, column, expression, params));
    }
    
    /**
     * 添加表达式片段
     *
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param isOR       是否为 or 条件
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child expression(boolean flag, boolean isOR, SFunc<E, ?> column, Ops opt, String expression, Object... params) {
        return addCondition(!flag ? null : createExpression(isOR, opt, column, expression, params));
    }
    
    /**
     * 添加表达式片段，此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param isOR       是否为 or 条件
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @return 当前查询器
     */
    public Child expression(boolean flag, boolean isOR, String column, Ops opt, String expression, Map<String, Object> paramMap) {
        return addCondition(!flag ? null : createExpression(isOR, opt, column, expression, paramMap));
    }
    
    /**
     * 添加表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param isOR       是否为 or 条件
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @param <E>        数据列类型
     * @return 当前查询器
     */
    public <E> Child expression(boolean flag, boolean isOR, SFunc<E, ?> column, Ops opt, String expression, Map<String, Object> paramMap) {
        return addCondition(!flag ? null : createExpression(isOR, opt, column, expression, paramMap));
    }
    
    // ************************************************
    // *************** and expressions ****************
    // ************************************************
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @return 当前查询器
     */
    public Child andExpression(boolean flag, String column, Ops opt, String expression, Object... params) {
        return expression(flag, false, column, opt, expression, params);
    }
    
    /**
     * 添加表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child andExpression(boolean flag, SFunc<E, ?> column, Ops opt, String expression, Object... params) {
        return expression(flag, false, column, opt, expression, params);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @return 当前查询器
     */
    public Child andExpression(boolean flag, String column, Ops opt, String expression, Map<String, Object> paramMap) {
        return expression(flag, false, column, opt, expression, paramMap);
    }
    
    /**
     * 添加表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child andExpression(boolean flag, SFunc<E, ?> column, Ops opt, String expression, Map<String, Object> paramMap) {
        return expression(flag, false, column, opt, expression, paramMap);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @return 当前查询器
     */
    public Child andExpression(String column, Ops opt, String expression, Object... params) {
        return andExpression(true, column, opt, expression, params);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child andExpression(SFunc<E, ?> column, Ops opt, String expression, Object... params) {
        return andExpression(true, column, opt, expression, params);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @return 当前查询器
     */
    public Child andExpression(String column, Ops opt, String expression, Map<String, Object> paramMap) {
        return andExpression(true, column, opt, expression, paramMap);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child andExpression(SFunc<E, ?> column, String expression, Ops opt, Map<String, Object> paramMap) {
        return andExpression(true, column, opt, expression, paramMap);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @return 当前查询器
     */
    public Child andExpression(Predicate<ColumnData<String, Object[]>> predicate, String column, Ops opt, String expression, Object... params) {
        return andExpression(predicate.test(new ColumnData<>(column, params)), column, opt, expression, params);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child andExpression(Predicate<ColumnData<SFunc<E, ?>, Object[]>> predicate, SFunc<E, ?> column, Ops opt, String expression, Object... params) {
        return andExpression(predicate.test(new ColumnData<>(column, params)), column, opt, expression, params);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @return 当前查询器
     */
    public Child andExpression(Predicate<ColumnData<String, Map<String, Object>>> predicate, String column, Ops opt, String expression, Map<String, Object> paramMap) {
        return andExpression(predicate.test(new ColumnData<>(column, paramMap)), column, opt, expression, paramMap);
    }
    
    /**
     * 添加 and 表达式片段
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child andExpression(Predicate<ColumnData<SFunc<E, ?>, Map<String, Object>>> predicate,
                                   SFunc<E, ?> column,
                                   String expression,
                                   Ops opt,
                                   Map<String, Object> paramMap) {
        return andExpression(predicate.test(new ColumnData<>(column, paramMap)), column, opt, expression, paramMap);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @return 当前查询器
     */
    public Child orExpression(boolean flag, String column, Ops opt, String expression, Object... params) {
        return expression(flag, true, column, opt, expression, params);
    }
    
    // ************************************************
    // *************** or expressions ****************
    // ************************************************
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child orExpression(boolean flag, SFunc<E, ?> column, Ops opt, String expression, Object... params) {
        return expression(flag, true, column, opt, expression, params);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @return 当前查询器
     */
    public Child orExpression(boolean flag, String column, Ops opt, String expression, Map<String, Object> paramMap) {
        return expression(flag, true, column, opt, expression, paramMap);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param flag       添加条件,当flag = true 表示。添加该条件，反之不添加
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child orExpression(boolean flag, SFunc<E, ?> column, Ops opt, String expression, Map<String, Object> paramMap) {
        return expression(flag, true, column, opt, expression, paramMap);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @return 当前查询器
     */
    public Child orExpression(
            String column,
            Ops opt,
            String expression,
            Object... params) {
        return orExpression(true, column, opt, expression, params);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child orExpression(SFunc<E, ?> column, Ops opt, String expression, Object... params) {
        return andExpression(true, column, opt, expression, params);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @return 当前查询器
     */
    public Child orExpression(String column, Ops opt, String expression, Map<String, Object> paramMap) {
        return andExpression(true, column, opt, expression, paramMap);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 and name like '%张三%'
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 and name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child orExpression(SFunc<E, ?> column, String expression, Ops opt, Map<String, Object> paramMap) {
        return orExpression(true, column, opt, expression, paramMap);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @return 当前查询器
     */
    public Child orExpression(Predicate<ColumnData<String, Object[]>> predicate,
                              String column,
                              Ops opt,
                              String expression,
                              Object... params) {
        return orExpression(predicate.test(new ColumnData<>(column, params)), column, opt, expression, params);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param params     SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child orExpression(Predicate<ColumnData<SFunc<E, ?>, Object[]>> predicate,
                                  SFunc<E, ?> column,
                                  Ops opt,
                                  String expression,
                                  Object... params) {
        return orExpression(predicate.test(new ColumnData<>(column, params)), column, opt, expression, params);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @return 当前查询器
     */
    public Child orExpression(Predicate<ColumnData<String, Map<String, Object>>> predicate,
                              String column,
                              Ops opt,
                              String expression,
                              Map<String, Object> paramMap) {
        return orExpression(predicate.test(new ColumnData<>(column, paramMap)), column, opt, expression, paramMap);
    }
    
    /**
     * 添加 or 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * <p>
     * 例如：
     * <pre>
     *     -- SELECT * from tab where 1=1 or name like '%张三%'
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ?
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < ${age}
     *     -- SELECT * from tab where 1=1 or name = '张三' and age < #{age}
     * </pre>
     * 上述代码中 以下部分 为自定义SQL
     * <pre>
     *     1、'%张三%'
     *     2、'张三' and age < ?
     *     3、'张三' and age < ${age}  注：${age} 最终是以 字符串方式拼接
     *     4、'张三' and age < #{age}
     * </pre>
     *
     * @param opt        条件关键字
     * @param predicate  自定义条件判断
     * @param column     数据列
     * @param expression SQL 表达式片段。此种方式是不安全的 因为它可能会发生SQL注入问题， 请自行注意 SQL 编码规范
     * @param paramMap   SQL 片段参数
     * @param <E>        实体类型
     * @return 当前查询器
     */
    public <E> Child orExpression(Predicate<ColumnData<SFunc<E, ?>, Map<String, Object>>> predicate, SFunc<E, ?> column, String expression, Ops opt, Map<String, Object> paramMap) {
        return orExpression(predicate.test(new ColumnData<>(column, paramMap)), column, opt, expression, paramMap);
    }
    
    
}
